package com.ofood.data.service.impl;

import com.ofood.data.config.RabbitMQConfig;
import com.ofood.data.dao.IFoodDao;
import com.ofood.data.service.IFoodService;
import com.ofood.domain.Food;
import com.ofood.utils.JsonUtils;
import com.ofood.utils.redis.RedisClient;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
public class FoodService implements IFoodService {
    private static final String FOOD_REDIS_KEY = "ofood:b:food:";
    @Autowired
    private IFoodDao foodDao;

    @Autowired
    private RedisClient redisClient;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * @param foodId food id
     * @return food
     */
    @Override
    public Food getFoodById(Long foodId) {
        String redisKey = FOOD_REDIS_KEY + foodId;
        String foodJson = redisClient.get(redisKey);
        Food food = null;

        try {
            if (!StringUtils.isEmpty(foodJson)) {
                food = JsonUtils.json2pojo(foodJson, Food.class);
                return food;
            }

            food = foodDao.getFoodById(foodId);

            if(food!=null) {
                foodJson = JsonUtils.obj2json(food);
                redisClient.set(redisKey, foodJson);
            }
        } catch (Exception e) {
            throw new RuntimeException("getFoodById_error_"+e);
        }

        return food;
    }

    /**
     * @param food
     * @return insert result
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public boolean insertFood(Food food) {
        if (food == null) {
            return false;
        }

        try {
            Integer result = foodDao.insertFood(food);

            /**
             * TODO:
             * send message to mq
             */
            String messageId = UUID.randomUUID().toString();
            String message = JsonUtils.obj2json(food);
            String messageCreateTime= LocalDateTime.now().toString();

            Map foodMessageMap=new HashMap();
            foodMessageMap.put("messageId",messageId);
            foodMessageMap.put("message",message);
            foodMessageMap.put("messageCreateTime",messageCreateTime);

            if (result != null && result > 0) {
                for(int i=0;i<10000000;i++) {
                    rabbitTemplate.convertAndSend(RabbitMQConfig.ITEM_TOPIC_EXCHANGE, "ofood.data.food.insert", foodMessageMap);
                }
                return true;
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return false;
    }

    /**
     * @param foodId
     * @return delete result
     */
    @Override
    public boolean deleteFood(Long foodId) {
        if (foodId == null && foodId <= 0) {
            return false;
        }

        Integer result = foodDao.deleteFood(foodId);

        /**
         * TODO:
         * send message to mq
         */

        redisClient.del(FOOD_REDIS_KEY+foodId);

        if (result != null && result > 0) {
            /*send message mq*/
            return true;
        }

        return false;
    }

    /**
     * @param food
     * @return update result
     */
    @Override
    public boolean updateFood(Food food) {
        if (food == null) {
            return false;
        }

        Integer result = foodDao.updateFood(food);

        /**
         * TODO:
         * send message to mq
         */

        redisClient.del(FOOD_REDIS_KEY+food.getId());

        if (result != null && result > 0) {
            /*send message mq*/
            return true;
        }

        return false;
    }

    /**
     * get all food
     *
     * @return
     */
    @Override
    public List<Food> getAllFood() {
        return foodDao.getAllFood();
    }
}
